package com.zz.level;

import java.awt.geom.Point2D;
import java.util.ArrayList;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Rectangle;

import com.zz.entity.Player;
import com.zz.pathfinding.Path;
import com.zz.tiles.Floor;
import com.zz.tiles.Tile;
import com.zz.tiles.Wall;

public abstract class Level {
	
	public int height = 15;
	public int width = 15;
	public int[][] level;
	public Tile[][] map = new Tile[width][height];
	private boolean[][] visited = new boolean[width][height];
	public Player[][] units = new Player[width][height];
	public int selectedx = -1;
	public int selectedy = -1;
	public int lastFindX = -1;
	public int lastFindY = -1;
	public ArrayList<Point2D.Float> playerStart = new ArrayList<Point2D.Float>();

	public Level() {
		//getTileMap();
	}
	
	public void getTileMap() {
		for(int i=0; i < this.height; i++) {
			for(int j = 0; j < this.width; j++) {
				if(level[i][j] == 0)
					map[i][j] = new Floor();
				else if(level[i][j] == 1)
					map[i][j] = new Wall(this, getNeighbours(i, j));
				else if(level[i][j] == 2) {
					map[i][j] = new Floor();
					this.playerStart.add(new Point2D.Float(i, j));
				}
				else
					map[i][j] = new Wall(this, 0);
					
			}
		}
	}
	
	public void draw(Path path, Graphics g) {

		for (int x=0;x<getWidthInTiles();x++) {
			for (int y=0;y<getHeightInTiles();y++) {
				if (getTerrain(x, y) != null)
					getTerrain(x, y).image.draw(x * Tile.size, y * Tile.size , null);
				if (getUnit(x, y) != null) {
					getUnit(x, y).anim.draw(x * Tile.size, y * Tile.size - Tile.size / 3, null);
					System.out.println("playerhere\n");
				} else {
					if (path != null) {
						if (path.contains(x, y)) {
							g.setColor(Color.red);
							g.fill(new Rectangle((x * Tile.size) + Tile.size / 2 - 1 , (y * Tile.size) + Tile.size / 2 - 1, 7, 7));
							g.setColor(Color.white);
						}
					}	
				}
			}
		}

		// if a unit is selected then draw a box around it
		if (selectedx != -1) {
			g.setColor(Color.black);
			g.drawRect(selectedx*Tile.size, selectedy*Tile.size, Tile.size - 1, Tile.size -1);
			g.drawRect((selectedx*Tile.size)-2, (selectedy * Tile.size)-2, Tile.size + 3, Tile.size + 3);
			g.setColor(Color.white);
			g.drawRect((selectedx*Tile.size)-1, (selectedy * Tile.size)-1, Tile.size + 1, Tile.size + 1);
		}
		
	}
	
	public Tile getTerrain(int x, int y) {
		return map[x][y];
	}
	
	public Point2D getPos(Player e) {
		return e.position;
	}
	
	public Player getUnit(int x, int y) {
		return units[x][y];
	}
	public void setUnit(int x, int y, Player unit) {
		units[x][y] = unit;
	}
	
	public void clearVisited() {
		for (int x=0;x<getWidthInTiles();x++) {
			for (int y=0;y<getHeightInTiles();y++) {
				visited[x][y] = false;
			}
		}
	}
	
	public int getNeighbours(int x, int y) {
		int im = 0;
		//System.out.println(x + ", " + y);
			if(x > 0 && level[x - 1][y] == 1)
				im += 1000;
			if(x < width - 1 && level[x + 1][y] == 1)
				im += 10;
			if(y < height - 1 && level[x][y + 1] == 1)
				im += 100;
			if(y > 0 && level[x][y - 1] == 1)
				im += 1;
		return im;
	}
	
	public boolean canMoveUp(Player player) {
		try{
			if(map[(int) player.position.getX()][(int) player.position.getY() - 1].isBlocking())
				return false;
			else
				return true;
		}catch(Exception e) {
			
		}
		return false;
	}

	public boolean canMoveDown(Player player) {
		try{
			if(map[(int) player.position.getX()][(int) player.position.getY() + 1].isBlocking())
				return false;
			else
				return true;
		}catch(Exception e) {
			
		}
		return false;
	}

	public boolean canMoveLeft(Player player) {
		try{
			if(map[(int) player.position.getX() - 1][(int) player.position.getY()].isBlocking())
				return false;
			else
				return true;
		}catch(Exception e) {
			
		}
		return false;
	}

	public boolean canMoveRight(Player player) {
		try{
			if(map[(int) player.position.getX() + 1][(int) player.position.getY()].isBlocking())
				return false;
			else
				return true;
		}catch(Exception e) {
			
		}
		return false;
	}

	public int getWidthInTiles() {
		return width;
	}
	
	public int getHeightInTiles() {
		return height;
	}
	
	public float getCost(Player player, int sx, int sy, int tx, int ty) {
		return 1;
	}
	
	public void pathFinderVisited(int x, int y) {
		visited[x][y] = true;
	}

	public ArrayList<Player> getPlayers(ArrayList<Player> players) {
		for(Player p : players) {
			p.setPosition(this, playerStart.remove(0));
		}
		return players;
	}
}
